package remote

import (
	"fmt"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commLogger"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisRpc"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisStatus"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/String"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"gitee.com/fierce_wolf/go-fox-edge-iot-common/iotCmdDict"
	mqtt "github.com/eclipse/paho.mqtt.golang"
	"go-fox-edge-iot-fastbee/service"
	"strings"
	"time"
)

type mqttHandler struct {
	deviceName string
	productId  interface{}
	deviceNum  interface{}
}

func (e *mqttHandler) MqttHandler() mqtt.MessageHandler {
	return func(client mqtt.Client, msg mqtt.Message) {
		topic := strings.ToLower(msg.Topic())
		if !strings.HasSuffix(topic, "/function/get") {
			return
		}

		e.handleRespond(topic, string(msg.Payload()))
	}
}

func (e *mqttHandler) handleRespond(topic, json string) {
	defer func() {
		if r := recover(); r != nil {
			commLogger.Console.Error(fmt.Sprintf("config() 捕获到异常:%v", r))
		}
	}()

	if json == "" {
		return
	}

	// 解析topic的格式：/{productId}/{deviceNum}/function/get
	items := strings.Split(topic, "/")
	if len(items) < 3 {
		return
	}
	productId := strings.ToUpper(items[1])
	deviceNum := strings.ToUpper(items[2])

	// 检查：输入参数是否有效
	if Method.HasEmpty(productId, deviceNum, json) {
		return
	}

	// 找出对应的DeviceEntity
	entity := e.getDeviceEntity(productId, deviceNum)
	if entity == nil {
		return
	}
	deviceEntity := entity.(*edgeEntity.DeviceEntity)

	// 通过时间戳，判断设备服务是否正在运行
	if !commRedisStatus.IsActive("device", "device", 60*1000) {
		return
	}

	// 将操作请求，提交给设备服务
	list := Json.BuildMapListByJson(json)
	for _, cmd := range list {
		respondVO := e.execute(deviceEntity, cmd)
		if respondVO != nil {
			commLogger.Info("来自云端的请求操作完成：设备名称->" + deviceEntity.DeviceName + " cmd->" + Json.BuildJson(cmd))
		} else {
			commLogger.Info("来自云端的请求操作失败：设备名称->" + deviceEntity.DeviceName + " cmd->" + Json.BuildJson(cmd))
		}
	}

}

func (e *mqttHandler) execute(deviceEntity *edgeEntity.DeviceEntity, cmd map[string]interface{}) *commRedisRpc.TaskRespondVO {
	id := Map.GetString(cmd, "id", "")
	value := Map.GetString(cmd, "value", "")
	remark := Map.GetString(cmd, "remark", "")

	if Method.HasEmpty(id, value, remark) {
		return nil
	}

	iotName := service.FastBeeService.IotName
	subsetName := service.FastBeeService.SubsetName

	// 构造操作请求
	requestVO := iotCmdDict.BuildTaskRequestVO(deviceEntity, iotName, subsetName, id, value)
	if requestVO == nil {
		return nil
	}

	// 向设备服务，发出操作请求
	err := commRedisRpc.Device.Client.Request.Push(requestVO)
	if err != nil {
		return nil
	}

	// 等待设备服务响应
	respondVO, err := commRedisRpc.Device.Client.Respond.Pop(requestVO.Uuid, time.Duration(requestVO.Timeout)*time.Millisecond)
	if err != nil {
		return nil
	}
	return respondVO
}

func (e *mqttHandler) getDeviceEntity(productId, deviceNum string) commEntity.IEntity {
	return commEntityManager.FindEntity(edgeEntity.Type.DeviceEntity.Type(), func(value commEntity.IEntity) bool {
		deviceEntity := value.(*edgeEntity.DeviceEntity)

		pid := deviceEntity.ExtendParam[service.FastBeeService.ProductId]
		num := deviceEntity.ExtendParam[service.FastBeeService.DeviceNum]

		strings.ToUpper(String.ToString(pid))

		return productId == strings.ToUpper(String.ToString(pid)) && deviceNum == strings.ToUpper(String.ToString(num))
	})
}
